//
//  Controller.hpp
//  C3W_Demo_By_Fan
//
//  Created by 范静涛 on 2024/7/22.
//

//------------------------------------------------------------------------------
//【文件名】Controller.hpp
//【功能模块和目的】控制器类声明
//【开发者及日期】范静涛 2024/7/22
//【更改记录】2024/8/9 范静涛 修改所有控制器公开成员函数返回值对应字符串标识符为RES_STR
//------------------------------------------------------------------------------

#ifndef Controller_hpp
#define Controller_hpp

//size_t所属头文件
#include <cstddef>
//Model3D类所属头文件
#include "Model3D.hpp"
//size_t所属头文件
#include <cstddef>
//Point3D类所属头文件
#include "Point3D.hpp"
//Face3D类所属头文件
#include "Face3D.hpp"
//Line3D类所属头文件
#include "Line3D.hpp"
//std::vector所属头文件
#include <vector>
//std::shared_ptr所属头文件
#include <memory>
//std::string所属头文件
#include <string>


//marco trick
#define enum_to_string(x) #x

//------------------------------------------------------------------------------
//【类名】Controller
//【功能】控制器类，具有用户可调用的全部层级功能，单例模式
//【接口说明】
//    静态：获取控制器实例指针
//    虚析构函数（可能做基类）
//    创建空模型并设为当前模型
//    设置指定模型为当前模型
//    删除指定模型
//    导入指定文件到指定模型
//    导出指定模型到指定文件
//    导入指定文件到当前模型
//    导出当前模型到指定文件
//    移除指定模型中的指定面
//    移除当前模型中的指定面
//    向指定模型添加指定面
//    向当前模型添加指定面
//    移除指定模型中的指定线
//    移除当前模型中的指定线
//    向指定模型添加指定线
//    向当前模型添加指定线
//    修改指定模型指定面中的指定点
//    修改当前模型指定面中的指定点
//    修改指定模型指定线中的指定点
//    修改当前模型指定线中的指定点
//    列出所有模型信息
//    列出指定模型信息
//    列出当前模型信息
//    列出指定模型中所有面信息
//    列出当前模型中所有面信息
//    列出指定模型中所有线信息
//    列出当前模型中所有线信息
//    列出指定模型指定面中所有点信息
//    列出当前模型指定面中所有点信息
//    列出指定模型指定线中所有点信息
//    列出当前模型指定线中所有点信息
//    当前模型索引（只读）
//【开发者及日期】 范静涛 2024/7/21
//【更改记录】2024/8/9 范静涛 修改所有控制器公开成员函数返回值对应字符串标识符为RES_STR
//------------------------------------------------------------------------------
class Controller{
public:
    //--------------------------------------------------------------------------
    //与数据交换相关的内嵌类
    //--------------------------------------------------------------------------
    //所有控制器公开成员函数返回值的枚举类型
    enum class RES : int{
        OK                             =  0,
        MODEL_INDEX_ERROR              =  1,
        FACE_INDEX_ERROR               =  2,
        LINE_INDEX_ERROR               =  3,
        POINT_INDEX_ERROR              =  4,
        IMPORTER_ERROR                 =  5,
        EXPORTER_ERROR                 =  6,
        FILE_TYPE_ERROR                =  7,
        FILE_OPEN_ERROR                =  8,
        DUPLICATE_FACE_IN_MODEL_ERROR  =  9,
        DUPLICATE_LINE_IN_MODEL_ERROR  = 10,
        DUPLICATE_POINT_IN_FACE_ERROR  = 11,
        DUPLICATE_POINT_IN_LINE_ERROR  = 12,
        DUPLICATE_IMPORTER_ERROR       = 13,
        DUPLICATE_EXPORTER_ERROR       = 14,
        UNKNOWN_ERROR                  = 15
    };
        
    //模型信息
    class ModelInfo{
    public:
        std::string Name;
        size_t FaceCount;
        double Area;
        size_t LineCount;
        double Length;
        size_t PointCount;
        double Volumn;
    };
    
    //点信息
    class PointInfo{
    public:
        double X;
        double Y;
        double Z;
    };
    
    //线信息
    class LineInfo{
    public:
        PointInfo PointsInfo[3];
        double Length;
    };

    //面信息
    class FaceInfo{
    public:
        PointInfo PointsInfo[3];
        double Area;
    };
    
    //模型信息列表
    using ModelInfoList    = std::vector<ModelInfo>;
    
    //点信息列表
    using PointInfoList    = std::vector<PointInfo>;
    
    //线信息列表
    using LineInfoList     = std::vector<LineInfo>;
    
    //面信息列表
    using FaceInfoList     = std::vector<FaceInfo>;

    //--------------------------------------------------------------------------
    //必要的构造、析构、赋值行为
    //--------------------------------------------------------------------------
    //单例模式，不允许拷贝
    Controller(const Controller& Source) = delete;
    //单例模式不允许赋值
    Controller& operator=(const Controller Source) = delete;
    //虚析构函数（可能做基类），无动态构造成员，默认实现
    virtual ~Controller() = default;
    
    //--------------------------------------------------------------------------
    //非静态Setter成员函数
    //--------------------------------------------------------------------------
    //模型相关非静态Setter成员函数
    //创建空模型并设为当前模型
    RES CreateAndSetToCurrent();
    //设置指定模型为当前模型
    RES SeleteCurrentModel(size_t ModelIndex);
    //删除指定模型
    RES RemoveModel(size_t ModelIndex);
    //导入指定文件到指定模型
    RES ImportModel(const std::string& FileName, size_t ModelIndex);
    //导出指定模型到指定文件
    RES ExportModel(const std::string& FileName, size_t ModelIndex);
    //导入指定文件到当前模型
    RES ImportCurrentModel(const std::string& FileName);
    //导出当前模型到指定文件
    RES ExportCurrentModel(const std::string& FileName);
    //面相关非静态Setter成员函数
    //移除指定模型中的指定面
    RES RemoveFaceFromModel(size_t ModelIndex, size_t FaceIndex);
    //移除当前模型中的指定面
    RES RemoveFaceFromCurrentModel(size_t FaceIndex);
    //向指定模型添加指定面
    RES AppendFaceToModel(size_t ModelIndex, const Face3D& AFace);
    //向当前模型添加指定面
    RES AppendFaceToCurrentModel(const Face3D& AFace);
    //线相关非静态Setter成员函数
    //移除指定模型中的指定线
    RES RemoveLineFromModel(size_t ModelIndex, size_t LineIndex);
    //移除当前模型中的指定线
    RES RemoveLineFromCurrentModel(size_t LineIndex);
    //向指定模型添加指定线
    RES AppendLineToModel(size_t ModelIndex, const Line3D& ALine);
    //向当前模型添加指定线
    RES AppendLineToCurrentModel(const Line3D& ALine);
    //点相关非静态Setter成员函数
    //修改指定模型指定面中的指定点
    RES ModifyPointInFaceOfModel(
        size_t ModelIndex,
        size_t FaceIndex,
        size_t PointIndex,
        const Point3D& APoint);
    //修改当前模型指定面中的指定点
    RES ModifyPointInFaceOfCurrentModel(
        size_t FaceIndex,
        size_t PointIndex,
        const Point3D& APoint);
    //修改指定模型指定线中的指定点
    RES ModifyPointInLineOfModel(
        size_t ModelIndex,
        size_t LineIndex,
        size_t PointIndex,
        const Point3D& APoint);
    //修改当前模型指定线中的指定点
    RES ModifyPointInLineOfCurrentModel(
        size_t LineIndex,
        size_t PointIndex,
        const Point3D& APoint);
    
    //--------------------------------------------------------------------------
    //静态Setter/Getter共用成员函数
    //--------------------------------------------------------------------------
    //获取控制器实例指针
    static std::shared_ptr<Controller> GetInstance();
    
    //--------------------------------------------------------------------------
    //非静态Getter成员函数：需检查所有Getter是否有后置const
    //--------------------------------------------------------------------------
    //模型相关非静态Getter成员函数
    //列出所有模型信息
    RES ListModels(ModelInfoList& InfoList);
    //列出指定模型信息
    RES ListModle(size_t ModelIndex, ModelInfo& Info);
    //列出当前模型信息
    RES ListCurrentModel(ModelInfo& Info);
    //面相关非静态Getter成员函数
    //列出指定模型中所有面信息
    RES ListFacesInModel(size_t ModelIndex, FaceInfoList& InfoList);
    //列出当前模型中所有面信息
    RES ListFacesInCurrentModel(FaceInfoList& InfoList);
    //线相关非静态Getter成员函数
    //列出指定模型中所有线信息
    RES ListLinesInModel(size_t ModelIndex, LineInfoList& InfoList);
    //列出当前模型中所有线信息
    RES ListLinesInCurrentModel(LineInfoList& InfoList);
    //点相关非静态Getter成员函数
    //列出指定模型指定面中所有点信息
    RES ListPointsInFaceOfModel(
        size_t ModelIndex,
        size_t FaceIndex,
        PointInfoList& InfoList);
    //列出当前模型指定面中所有点信息
    RES ListPointsInFaceOfCurrentModel(
        size_t FaceIndex,
        PointInfoList& InfoList);
    //列出指定模型指定线中所有点信息
    RES ListPointsInLineOfModel(
        size_t ModelIndex,
        size_t LineIndex,
        PointInfoList& InfoList);
    //列出当前模型指定线中所有点信息
    RES ListPointsInLineOfCurrentModel(
        size_t LineIndex,
        PointInfoList& InfoList);

    //--------------------------------------------------------------------------
    //非静态Getter数据成员：常引用
    //--------------------------------------------------------------------------
    //当前模型索引值
    const size_t& CurrentModelIndex{m_CurrentModelIndex};
    
    //--------------------------------------------------------------------------
    //静态Getter数据成员
    //--------------------------------------------------------------------------
    //所有控制器公开成员函数返回值，对应的字符串
    static const std::string RES_STR[];

private:
    //--------------------------------------------------------------------------
    //私有 必要的构造、析构、赋值行为
    //--------------------------------------------------------------------------
    //单例模式，使用私有默认构造函数
    Controller();
    
    //--------------------------------------------------------------------------
    //私有 非静态数据成员
    //--------------------------------------------------------------------------
    //当前模型索引
    size_t m_CurrentModelIndex{SIZE_T_MAX};
    //所有模型实例指针列表
    std::vector<std::shared_ptr<Model3D>> m_Models{};
    
    //--------------------------------------------------------------------------
    //私有 静态数据成员
    //--------------------------------------------------------------------------
    //控制器实例指针
    static std::shared_ptr<Controller> m_pControllerIntance;
};

#endif /* Controller_hpp */
